﻿// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// Copyright (c) 2011, Dr. Masroor Ehsan
// All rights reserved.
// 
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//     * Neither the name of the author nor the
//       names of its contributors may be used to endorse or promote products
//       derived from this software without specific prior written permission.
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// 
// $Author: masroore@gmail.com $
// $Id: FirebirdPersistenceMapping.cs 40 2011-10-23 14:44:55Z masroore@gmail.com $
// $Rev: 40 $
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

using System;
using System.Collections.Generic;
using MaxTrader.Core;
using MaxTrader.Persistence.Core;

namespace MaxTrader.Persistence.Firebird
{
    public class FirebirdPersistenceMapping : Singleton<FirebirdPersistenceMapping>, IPersistenceMapping
    {
        private readonly Dictionary<string, string> _dict;

        private static readonly Dictionary<Type, string> _dataTypeMap = new Dictionary<Type, string>
                                                                            {
                                                                                // Integral types
                                                                                {typeof (int), @"INT"},
                                                                                {typeof (Int64), @"INT64"},
                                                                                {typeof (short), @"SMALLINT"},
                                                                                {typeof (sbyte), @"SMALLINT"},
                                                                                // Custom user types
                                                                                {typeof (Money), @"DECIMAL(14,2)"},
                                                                                {typeof (TradingDate), @"TIMESTAMP"},
                                                                                {typeof (TradingTime), @"TIMESTAMP"},
                                                                            };

        public FirebirdPersistenceMapping()
        {
            _dict = new Dictionary<string, string>
                        {
                            // StockExchange ////////////////////////////////////////////////
                            {"StockExchange.__TABLE__", "STOCK_EXCHANGES"},
                            {"StockExchange.__SEQUENCE__", "SEQ_EXCHANGES"},
                            {"StockExchange.Id", "EXCH_ID"},
                            {"StockExchange.Name", "EXCH_NAME"},
                            {"StockExchange.Symbol", "EXCH_SYMBOL"},

                            // MarketSector /////////////////////////////////////////////////
                            {"MarketSector.__TABLE__", "MARKET_SECTORS"},
                            {"MarketSector.__SEQUENCE__", "SEQ_SECTORS"},
                            {"MarketSector.Id", "SECT_ID"},
                            {"MarketSector.Name", "SECT_NAME"},
                            {"MarketSector.Symbol", "SECT_SYMBOL"},

                            // Transaction /////////////////////////////////////////////////
                            {"Transaction.__TABLE__", "TRANSACTIONS"},
                            {"Transaction.__SEQUENCE__", "SEQ_TRANSACTIONS"},
                            {"Transaction.Id", "TRANS_ID"},
                            {"Transaction.Date", "TRANS_DATE"},
                            {"Transaction.Category", "TRANS_CATEGORY"},
                            {"Transaction.Type", "TRANS_TYPE"},
                            {"Transaction.Portfolio", "TRANS_PORTFOLIO"},
                            {"Transaction.CashAccount", "TRANS_CASH_ACCT"},
                            {"Transaction.CashAccount2", "TRANS_CASH_ACCT2"},
                            {"Transaction.ShareAccount", "TRANS_SHARE_ACCT"},
                            {"Transaction.Amount", "TRANS_AMOUNT"},
                            {"Transaction.TradeCost", "TRANS_COST"},
                            {"Transaction.Symbol", "TRANS_SYMBOL"},
                            {"Transaction.Price", "TRANS_PRICE"},
                            {"Transaction.IsMarged", "TRANS_MARGED"},
                            {"Transaction.OrderSide", "TRANS_SIDE"},
                            {"Transaction.NumberOfShares", "TRANS_SHARES"},

                            // Account /////////////////////////////////////////////////////
                            {"Account.__TABLE__", "ACCOUNTS"},
                            {"Account.__SEQUENCE__", "SEQ_ACCOUNTS"},
                            {"Account.Id", "ACCT_ID"},
                            {"Account.Type", "ACCT_TYPE"},
                            {"Account.AccountName", "ACCT_NAME"},
                            {"Account.Currency", "ACCT_FXCODE"},
                            {"Account.Capital", "ACCT_CAPITAL"},
                            {"Account.Portfolio", "ACCT_PORTFOLIO"},

                            // StockSymbol /////////////////////////////////////////////////
                            {"StockSymbol.__TABLE__", "STOCK_SYMBOLS"},
                            {"StockSymbol.__SEQUENCE__", "SEQ_SYMBOLS"},
                            {"StockSymbol.Id", "SYMBOL_ID"},
                            {"StockSymbol.Category", "SYMBOL_CAT"},
                            {"StockSymbol.Sector", "SYMBOL_SECTOR"},
                            {"StockSymbol.DseId", "SYMBOL_DSE_ID"},
                            {"StockSymbol.DseSymbol", "SYMBOL_DSE_SCRIP"},
                            {"StockSymbol.CseId", "SYMBOL_CSE_ID"},
                            {"StockSymbol.CseSymbol", "SYMBOL_CSE_SCRIP"},
                            {"StockSymbol.CompanyName", "SYMBOL_FULL_NAME"},

                            // Portfolio ////////////////////////////////////////////////////
                            {"Portfolio.__TABLE__", "PORTFOLIOS"},
                            {"Portfolio.__SEQUENCE__", "SEQ_PORTFOLIOS"},
                            {"Portfolio.Id", "PORT_ID"},
                            {"Portfolio.PortfolioName", "PORT_NAME"},
                            {"Portfolio.Currency", "PORT_FXCODE"},
                            {"Portfolio.StockExchange", "PORT_EXCHANGE"},
                            {"Portfolio.ShareAccount", "PORT_SHARE_ACCT"},
                        };
        }

        #region IPersistenceMapping Members

        public string GetTableName(string className)
        {
            return _dict[String.Format("{0}.__TABLE__", className)];
        }

        public string GetColumnName(string className, string memberName)
        {
            return _dict[String.Format("{0}.{1}", className, memberName)];
        }

        public string GetGeneratorName(string className)
        {
            return _dict[String.Format("{0}.__SEQUENCE__", className)];
        }

        public string GetColumnNameWithMoneyAmount(string className, string memberName)
        {
            return _dict[String.Format("{0}.{1}", className, memberName)] + "_AMOUNT";
        }

        public string GetColumnNameWithCurrencyCode(string className, string memberName)
        {
            return _dict[String.Format("{0}.{1}", className, memberName)] + "_FXCODE";
        }

        public string IndexName(string className, string memberName)
        {
            return "IX_" + _dict[String.Format("{0}.{1}", className, memberName)];
        }

        public string ForeignKeyName(string className, string memberName)
        {
            return "FK_" + _dict[String.Format("{0}.{1}", className, memberName)];
        }

        public string MapClrTypeToDbType(Type type)
        {
            return _dataTypeMap.ContainsKey(type) ? _dataTypeMap[type] : String.Empty;
        }

        #endregion
    }
}